/*
 * @Author: firefly717
 * @Date: 2024-06-22 10:40:32
 * @LastEditTime: 2024-06-22 20:05:18
 * @Description:  抽象类、多态、继承、协议、混入
 */

void main() {
  // 多态+继承
  Animal dog = Dog('哈士奇', 9);
  print(dog.eat());
  // 使用父类Animal中的方法
  dog.description();

  Dog teddy = Teddy('安妮', 9, "棕色");
  print(teddy.eat());
  // 覆盖父类中的方法
  teddy.description();

  // 协议
  Cat cat = Cat();
  print(cat.eat());
  cat.description();

  // 混入
  final swan = WhiteSwan();
  swan.flyHeight = 11000;
  swan.fly();
  // Bird覆盖Animal方法
  swan.description();

  print(swan.eat());
}

// mixin可以替换为class,使用with混入的不需要改动
mixin Bird {
  num flyHeight = 0;

  bool get canFlyHigh {
    if (flyHeight > 2000) {
      return true;
    }
    return false;
  }

  void fly() {
    if (this is WhiteSwan) {
      print("白天鹅能飞越喜马拉雅山，飞行高度$flyHeight米 \n");
    } else if (canFlyHigh) {
      print("鸟能飞$flyHeight米");
    } else {
      print("鸟会飞");
    }
  }

  String eat() {
    print("Bird=>吃虫子");
    return "吃点小虫子吧";
  }

  description() {
    if (this is WhiteSwan) {
      print("这是一只白天鹅 \n");
    } else {
      print("这是一只不可描述的鸟 \n");
    }
  }
}

// 抽象类
abstract class Animal {
  // 是否为大型动物
  bool bigAnimal = false;

  int get legs;

  String eat() {
    print("Animal=>想吃啥吃啥");
    return '啥都行';
  }

  description() {
    if (bigAnimal) {
      print("这是一只大型动物 \n");
    } else {
      print("这是一只小型动物 \n");
    }
  }
}

// 继承，有默认实现可以不用再次实现
class Dog extends Animal {
  final String name;
  final int age;
  Dog(this.name, this.age);
  @override
  eat() {
    return "$name爱吃🦴";
  }

  @override
  int get legs => 4;
}

class Teddy extends Dog {
  final String color;
  Teddy(
    String name,
    int age,
    this.color,
  ) : super(name, age);

  @override
  eat() {
    return "$name爱吃肉肉";
  }

  description() {
    print("这是一只$color的小泰迪$name \n");
  }
}

// Interface，需要实现所有属性和方法
class Cat implements Animal {
  @override
  eat() {
    return "小猫爱吃鱼";
  }

  @override
  int get legs => 4;

  @override
  bool bigAnimal = false;

  @override
  description() {
    print("可可爱爱的小猫咪 \n");
  }
}

// 继承+混入
class WhiteSwan extends Animal with Bird {
  @override
  eat() {
    return "白天鹅不知道吃什么，问问父类：${super.eat()}";
  }

  @override
  int get legs => 2;

  @override
  bool get bigAnimal => true;
}
